package com.gitee.feizns.itrip.personal.utils.service.impl;

import com.gitee.feizns.itrip.personal.beans.dto.Token;
import com.gitee.feizns.itrip.personal.beans.pojo.User;
import com.gitee.feizns.itrip.personal.utils.service.TokenService;
import com.gitee.feizns.itrip.personal.utils.Utils;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.concurrent.TimeUnit;
import java.util.function.Function;

/**
 * @author feizns
 * @since 2019/1/8 0008
 */
public class TokenServiceImpl implements TokenService {

    /**
     * 缓存数据中token与user信息的分隔符
     */
    private static final String DEFAULT_TOKEN_AND_USER_SPLIT = "^-^";

    private StringRedisTemplate redisTemplate;

    public TokenServiceImpl(StringRedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    /**
     * 生成 token 并注册到redis
     * @param user
     * @return
     */
    @Override
    public Token generatorToken(User user) {
        String tokenKey = Utils.getUUIDCode() + Utils.getMD5(user.toString()) + DEFAULT_TOKEN_AND_USER_SPLIT + user.getId();
        long curt = System.currentTimeMillis();
        Token token = new Token(tokenKey, curt + DEFAULT_TOKEN_VALID_TIME, curt);
        redisTemplate.opsForValue().set(tokenKey,
                Utils.toJSONString(token) + DEFAULT_TOKEN_AND_USER_SPLIT + Utils.toJSONString(user),
                DEFAULT_TOKEN_VALID_TIME,
                TimeUnit.MILLISECONDS);
        return token;
    }

    @Override
    public Token verification(String token) {
        return verification(token, TokenServiceImpl::splitTokenValAndGetToken);
    }

    @Override
    public void deleteToken(Token token) {
        redisTemplate.delete(token.getToken());
    }

    @Override
    public User getUser(String token) {
        return verification(token, TokenServiceImpl::splitTokenValAndGetUser);
    }

    //验证token
    private <R> R verification(String token, Function<String, R> fun) {
        if ( token != null ) {
            String val = redisTemplate.opsForValue().get(token);
            if ( val != null ) {
                User user = splitTokenValAndGetUser(val);
                String id = splitAndGetId(token);
                if ( id != null && id.equals(user.getId().toString()) ) {
                    return fun.apply(val);
                }
            }
        }
        return null;
    }

    //解析token的id值
    private static final String splitAndGetId(String token) {
        if ( token != null )
            return token.substring(token.lastIndexOf(DEFAULT_TOKEN_AND_USER_SPLIT) + DEFAULT_TOKEN_AND_USER_SPLIT.length());
        return null;
    }

    //解析缓存数据并获取value中的token对象
    private static final Token splitTokenValAndGetToken(String val) {
        if ( val != null )
            return Utils.parseObject(val.substring(0, val.lastIndexOf(DEFAULT_TOKEN_AND_USER_SPLIT)), Token.class);
        return null;
    }

    private static final User splitTokenValAndGetUser(String val) {
        if ( val != null )
            return Utils.parseObject(val.substring(val.lastIndexOf(DEFAULT_TOKEN_AND_USER_SPLIT) + DEFAULT_TOKEN_AND_USER_SPLIT.length()), User.class);
        return null;
    }

}
